package com.cn.udp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import  java.net.InetSocketAddress;
import  java.net.SocketAddress;
import  java.nio.ByteBuffer;
import  java.nio.channels.DatagramChannel;
import  java.nio.channels.SelectionKey;
import  java.nio.channels.Selector;
import  java.nio.charset.Charset;
import java.util.*;


public class  UDPClient  extends  Thread  {
    public  void  run () {
        DatagramChannel channel =  null ;
        Selector selector =  null ;
        InetSocketAddress sa = null;
        Map<String,InetSocketAddress> mapAddr = new HashMap<>();
        Map<String,DatagramChannel> mapChannel=new HashMap<>();
        List<InetSocketAddress> addrList = new ArrayList<>();
        JSONArray list = null;
        int udpPort=5000;
        try  {
            channel = DatagramChannel.open () ;
            channel.configureBlocking ( false ) ;
            sa =  new  InetSocketAddress ( "localhost" ,udpPort) ;

        }  catch  ( Exception e ) {
            e.printStackTrace () ;
        }

        try  {
            selector = Selector.open () ;
            channel.register (selector, SelectionKey.OP_READ ) ;
            int count=channel.send(Charset.defaultCharset().encode( "Tell me your time"),sa);
        }  catch  ( Exception e ) {
            e.printStackTrace () ;
        }

        ByteBuffer byteBuffer = ByteBuffer.allocate (100) ;
        while  ( true ) {
            try  {
                int  eventsCount = selector.select () ;
                if  ( eventsCount >  0 ) {
                    Set selectedKeys = selector.selectedKeys () ;
                    Iterator iterator = selectedKeys.iterator () ;
                    while  ( iterator.hasNext ()) {
                        SelectionKey sk =  ( SelectionKey )  iterator.next () ;
                        iterator.remove () ;
                        if  ( sk.isReadable ()) {
                            //在这里datagramChannel与channel实际是同一个对象
                            DatagramChannel datagramChannel =  ( DatagramChannel )  sk.channel () ;
                            byteBuffer.clear();
                            SocketAddress isa=datagramChannel.receive(byteBuffer);
                            System.out.println(isa.toString());
                            byteBuffer.flip () ;
                            // 测试：通过将收到的ByteBuffer首先通过缺省的编码解码成CharBuffer 再输出
                            String obj=Charset.defaultCharset().decode (byteBuffer ) .toString ();
                            System.out.println ( obj) ;
                            InetSocketAddress pISA=null;
                            if(obj!="" && obj!=null){
//                               List<> addrList = JSON.parseObject(obj,ArrayList.class);
                                list = JSON.parseArray(obj);
                                for (Object o: list){
                                    JSONObject jsonObject = JSON.parseObject(o.toString());
                                    pISA=new InetSocketAddress(jsonObject.getString("address"),jsonObject.getInteger("port"));
                                    addrList.add(pISA);
                                }
                            }
                            Thread.sleep(2000);//延时
                            int count=datagramChannel.send(Charset.defaultCharset ().encode ("hello server"),isa) ;

                            for(InetSocketAddress sAddr:addrList){
                                if(!sAddr.toString().equals(sa.toString())){ //不是自身的ip端口就通過
                                    int count3=channel.send(Charset.defaultCharset().encode( "Tell me your time22"),sAddr);
                                }
                            }
//                            for(InetSocketAddress addr: mapAddr.values()){
//                                if(!addr.toString().equals(sa.toString())){ //不是自身的ip端口就通過
//                                    if(!mapChannel.containsKey(addr.toString())){ //如果通道不存在，就新建通道
//                                        DatagramChannel cha = DatagramChannel.open () ;
//                                        cha.configureBlocking ( false ) ;
//                                        Selector selector2 = Selector.open () ;
//                                        channel.register (selector2, SelectionKey.OP_READ ) ;
//                                    }
//                                }
//                            }

                        }
                    }
                }
            }  catch  ( Exception e ) {
                e.printStackTrace () ;
            }
        }

    }

    public static void main (String[] args) {
        new UDPClient().start();
    }
}
